
#include "commmsg.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "cmdstorage.h"
#include "../equip/CEquipMgr.h"
#include "../storage/CStorageMgr.h"

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_GET_USER_STORAGE_INFO , CCmdGetUserStorageInfo);
int CCmdGetUserStorageInfo::Do(void* pData)
{
    //int iRet = 0;
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_GET_USER_STORAGE_INFO ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_GET_USER_STORAGE_INFO,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    _uiGID = stReq.gid();
    iRet = pstMainCtrl->CheckLogin(_uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdGetUserStorageInfo::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, stReq.gid());
    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", stReq.gid()));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("no detail ex1 data user(%u)", stReq.gid()));
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1 =
        pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }

    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    short sStorageType = stReq.storage_type();


    if (STORAGE_TYPE_ROLE_EQUIP == sStorageType)
    {
        pstMainCtrl->m_stEquipMgr.SendEquipInfoToFront(stPlayerDetailInfo, stPlayerOnlineData, 0, stMsgHead, stEnpHead);
    }
    else if (STORAGE_TYPE_CARD == sStorageType)
    {
        pstMainCtrl->m_stCardMgr.SendCardBagInfoToFront(stPlayerOnlineData._stUserCard, stMsgHead, stEnpHead);
    }
    else if (STORAGE_TYPE_TREASURE == sStorageType)
    {
        pstMainCtrl->m_stTreasureMgr.SendBriefTreasureToFront(stPlayerDetailInfo);
    }
    else if (STORAGE_TYPE_LUCKY_DIAL == sStorageType)
    {
        pstMainCtrl->m_stStorageMgr.SendActStorageToFront(stPlayerDetailEx1,
            ENM_ACT_STORAGE_LUCKY_DIAL);
    }
    else
    {        
        pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_BAG_INFO);        
    }

    return AnsClients(RET_OK);
}

int CCmdGetUserStorageInfo::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(RET_OK);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_SWAP_ITEM_POS, CCmdSwapStoragePos);
int CCmdSwapStoragePos::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_SWAP_ITEM_POS ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_SWAP_ITEM_POS,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdSwapStoragePos::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    ASSERT_PLAYER_PREPARED(stReq.gid());

    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    ASSERT_PLAYER_DETAIL_PREPARED(stReq.gid());

    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("user %u not in m_stPlayerOnlineDataHash", stReq.gid()));
        pstMainCtrl->SetOffline(stPlayerBaseInfo._uiGID, stEnpHead);
        return AnsClients(RET_SYSTEM_FAIL);

    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    CUserStorage& stUserStorage = stPlayerOnlineData._stUserStorage;

    CStorageGrid stGrid1;
    CStorageGrid stGrid2;

    if (stReq.storage_type1() == STORAGE_TYPE_CARD)
    {
        iRet = pstMainCtrl->m_stCardMgr.SwapStorageItemPos(stPlayerOnlineData._stUserCard, stReq.item1_pos(), stGrid1,
                                            stReq.item2_pos(), stGrid2);
        if (iRet)
        {
            return AnsClients(iRet);
        }

        pstMainCtrl->m_stCardMgr.GetData(stPlayerOnlineData._stUserCard, stPlayerDetailInfo._stUserCardData);
    }
    else
    {
        unsigned char ucStorageItem1 = (unsigned char)(stReq.storage_type1() & 0x7F);
        unsigned char ucStorageItem2 = (unsigned char)(stReq.storage_type2() & 0x7F);
        int iItem1Pos = stReq.item1_pos();
        int iItem2Pos = stReq.item2_pos();

        //双击背包物品加入到仓库/或者双击仓库物品加入到背包. 跟前台约定其中一个参数传入-1
        if ((-1 == iItem2Pos) || (-1 == iItem1Pos))
        {
            if ((iItem1Pos == iItem2Pos) || (ucStorageItem1 == ucStorageItem2))
            {
                return AnsClients(ERROR_STORAGE_INVALID_POS);
            }

            if (-1 == iItem2Pos)
            {
                if ((STORAGE_TYPE_BAG == ucStorageItem2)
                    && stUserStorage.BagIsFull())
                {
                    return AnsClients(ERROR_STORAGE_BAG_IS_FULL);
                }

                if ((STORAGE_TYPE_WARE == ucStorageItem2)
                    && stUserStorage.WareHouseIsFull())
                {
                    return AnsClients(ERROR_STORAGE_WAREHOUSE_IS_FULL);
                }
            }

            if (-1 == iItem1Pos)
            {
                if ((STORAGE_TYPE_BAG == ucStorageItem1)
                    && stUserStorage.BagIsFull())
                {
                    return AnsClients(ERROR_STORAGE_BAG_IS_FULL);
                }

                if ((STORAGE_TYPE_WARE == ucStorageItem1)
                    && stUserStorage.WareHouseIsFull())
                {
                    return AnsClients(ERROR_STORAGE_WAREHOUSE_IS_FULL);
                }
            }

            iRet = stUserStorage.SwapToEmptyGrid(ucStorageItem1, iItem1Pos, stGrid1,
                                                 ucStorageItem2, iItem2Pos, stGrid2);
        }
        else
        {
            //拖拽交互物品位置
            iRet = stUserStorage.SwapStorageItemPos(ucStorageItem1, iItem1Pos, stGrid1,
                                                    ucStorageItem2, iItem2Pos, stGrid2);
            if (RET_OK == iRet && stGrid1.IsEmpty() && stGrid2.IsEmpty())
            {
                //空格子交换,前台数据出错
                if (ucStorageItem1 == ucStorageItem2)
                {
                    pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), ((STORAGE_TYPE_BAG == ucStorageItem1) ? NOTIFY_BAG_INFO : NOTIFY_WARE_INFO));
                }
                else
                {
                    pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_BAG_INFO | NOTIFY_WARE_INFO);
                }
            }
        }

        if (iRet)
        {
            return AnsClients(iRet);
        }

        /*  保存格子的内容到Detail中*/
        iRet = pstMainCtrl->m_stStorageMgr.GetData(stUserStorage, stPlayerDetailInfo._stUserStorage);
        if (iRet)
        {
            return AnsClients(iRet);
        }
    }

    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    MsgGridItemInfo stGridItem;
    pstMainCtrl->m_stStorageMgr.GetGridInfo(stReq.gid(), stGrid1, stGridItem);
    stAns.set_storage_type1(stGrid1._stKey._bIsInBag ? STORAGE_TYPE_BAG : STORAGE_TYPE_WARE);
    *stAns.mutable_item1() = stGridItem;

    pstMainCtrl->m_stStorageMgr.GetGridInfo(stReq.gid(), stGrid2, stGridItem);
    stAns.set_storage_type2(stGrid2._stKey._bIsInBag ? STORAGE_TYPE_BAG : STORAGE_TYPE_WARE);
    *stAns.mutable_item2() = stGridItem;
    return AnsClients(RET_OK);
}

int CCmdSwapStoragePos::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_SORT_STORAGE, CCmdSortStorage);
int CCmdSortStorage::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_SORT_STORAGE ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_SORT_STORAGE,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdSortStorage::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    ASSERT_PLAYER_PREPARED(stReq.gid());

    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    ASSERT_PLAYER_DETAIL_PREPARED(stReq.gid());

    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("user %u not in m_stPlayerOnlineDataHash", stReq.gid()));
        pstMainCtrl->SetOffline(stPlayerBaseInfo._uiGID, stEnpHead);
        return AnsClients(RET_SYSTEM_FAIL);

    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    switch (stReq.storage_type())
    {
        case STORAGE_TYPE_BAG:
            {
                iRet = stPlayerOnlineData._stUserStorage.SortStorage(true);
            }
            break;

        case STORAGE_TYPE_WARE:
            {
                iRet = stPlayerOnlineData._stUserStorage.SortStorage(false);
            }
            break;

        default:
            iRet = ERROR_UNKOWN_STORAGE_TYPE;
            break;
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    //修改detail中保存的信息
    pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);

    //保存数据
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    return AnsClients(RET_OK);
}

int CCmdSortStorage::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);

    if (STORAGE_TYPE_BAG == stReq.storage_type())
    {
        pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_BAG_INFO);
    }
    else
    {
        pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_WARE_INFO);
    }

    pstMainCtrl->FlushSendCache();

    return Done(iRet);
}


CT_REGISTER_ASYNCCMD(ID_MAIN_MERGE_BAGTOWARE, CCmdMergBagToWare);
int CCmdMergBagToWare::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_MERGE_BAGTOWARE ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_MERGE_BAGTOWARE,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdMergBagToWare::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    ASSERT_PLAYER_DETAIL_PREPARED(stReq.gid());
    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", stReq.gid()));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }   
    CUserStorage & stUserStorage = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex]._stUserStorage;

    iRet = stUserStorage.MergeToWareHouse();
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //修改detail中保存的信息
    pstMainCtrl->m_stStorageMgr.GetData(stUserStorage, stPlayerDetailInfo._stUserStorage);

    //保存数据
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_BAG_INFO | NOTIFY_WARE_INFO);

    return AnsClients(RET_OK);
}

int CCmdMergBagToWare::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_DISCARD_ITEM, CCmdDiscardItem);
int CCmdDiscardItem::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_DISCARD_ITEM ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_DISCARD_ITEM,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdDiscardItem::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    ASSERT_PLAYER_PREPARED(stReq.gid());

    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    ASSERT_PLAYER_DETAIL_PREPARED(stReq.gid());

    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", stReq.gid()));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData & stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    CUserStorage & stUserStorage = stPlayerOnlineData._stUserStorage;
    const MsgGridItemInfo & stReqItem = stReq.item();
    CStorageGrid  stGrid;
    bool bIsInBag = ((unsigned char)(stReq.storage_type() & 0x7F) == STORAGE_TYPE_BAG);
    if (false == bIsInBag)
    {
        return AnsClients(RET_REMOVE_NOT_BAG_ITEM);
    }

    unsigned short usPos = (unsigned short)(stReqItem.item_store_pos() & 0x7FFF);
    iRet = pstMainCtrl->m_stStorageMgr.GetGridInfoByPos(stUserStorage, bIsInBag, usPos, stGrid);
    if (iRet)
    {
        return AnsClients(iRet);
    }
#if 0
    //前台处理64位数字有问题, 暂时无法使用item_aux_info字段  tony:2013/04/09
    //校验请求删除的信息.  
    if (stGrid._stKey._ucItemType == ITEM_TYPE_EQUIP)
    {
        if ((stGrid._stKey._uiItemID != (unsigned int)stReqItem.item_aux_info())
            || (stGrid._shCount != stReqItem.item_count()))
        {
            return AnsClients(RET_DISCARD_ITEM_INVALID);
        }
    }
    else
    {
        if ((stGrid._stKey._ucItemType !=  (unsigned int)stReqItem.item_type())
             || (stGrid._stKey._uiItemID !=  (unsigned int)stReqItem.item_config_id())
             || (stGrid._shCount != stReqItem.item_count()))
        {
            return AnsClients(RET_DISCARD_ITEM_INVALID);
        }
    }
#endif
    bool bCanDiscard;
    iRet = pstMainCtrl->m_stItemMgr.CheckCanOper(stGrid._stKey._ucItemType, (unsigned int)stReqItem.item_config_id(),
                                                 ITEM_OPER_DISCARD, bCanDiscard);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    if (!bCanDiscard)
    {
        return AnsClients(ERROR_ITEM_CANNOT_DISCARD);
    }

    pstMainCtrl->m_stOssMgr.ClearKeyValueList();//oss

    if (stGrid._stKey._ucItemType == ITEM_TYPE_EQUIP)   //删除装备
    {
        unsigned int uiEquipId = stGrid._stKey._uiItemID;
        CUserEquip& stUserEquip = stPlayerOnlineData._stUserEquip;
        iRet = pstMainCtrl->m_stEquipMgr.DelEquip(stUserEquip, uiEquipId);
        if (iRet != RET_OK)
        {
            return AnsClients(iRet);
        }

        pstMainCtrl->m_stEquipMgr.GetData(stPlayerOnlineData._stUserEquip, stPlayerDetailInfo._stUserEquip);
    }

    iRet = pstMainCtrl->m_stStorageMgr.TakeOutGrid(stUserStorage, usPos, stGrid);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    pstMainCtrl->m_stStorageMgr.GetData(stUserStorage, stPlayerDetailInfo._stUserStorage);

    pstMainCtrl->m_stOssMgr.TriggerItem(stPlayerDetailInfo._uiGID, OSS_ITEM_DISCARD);//oss

    //保存数据
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    stAns.set_storage_type(stReq.storage_type());
    *stAns.mutable_item() = stReq.item();
    return AnsClients(RET_OK);
}

int CCmdDiscardItem::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_ret(iRet);
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_PICK_UP_ITEM, CCmdPickUpItem);
int CCmdPickUpItem::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_PICK_UP_ITEM ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_PICK_UP_ITEM,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束


    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdPickUpItem::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    ASSERT_PLAYER_DETAIL_PREPARED(stReq.gid());
    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", stReq.gid()));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
    
    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    int iBagEmptyGrid = stPlayerOnlineData._stUserStorage.GetBagEmptyGridCount();
    int iCardEmptyGrid = stPlayerOnlineData._stUserCard.GetBagEmptyGridCount();
    int iNeedCardGrid = 0;

    pstMainCtrl->m_stOssMgr.ClearKeyValueList();//oss

    CDropItem stDropItem;
    for (int i = 0; i < stReq.groud_bag_pos_size(); ++i)
    {
        CStorageKey stKey;
        stKey._bIsInBag = true;
        stKey._usStorePos = stReq.groud_bag_pos(i) & 0x7FFF;

        CStorageGrid stGrid;
        iRet = pstMainCtrl->m_stStorageMgr.GetGridInfoByPos(stPlayerOnlineData._stUserGroudBag, true, stKey._usStorePos, stGrid);
        if (iRet != RET_OK)
        {
            return AnsClients(iRet);
        }

        if (stGrid.IsEmpty())
        {
            return AnsClients(ERROR_STORAGE_TAKE_OUT_NO_ITEM);
        }

        CDropItemData stDropItemData;
        stDropItemData._ucItemType = stGrid._stKey._ucItemType;
        stDropItemData._usItemConfigID = stGrid._stKey._uiItemID;
        stDropItemData._iItemCount = stGrid._shCount;        

        //检查是否会满
        if (stDropItemData._ucItemType == ITEM_TYPE_CARD)
        {
            iNeedCardGrid++;
        }

        /*
        CItemConfigData stItemConfigData;
        iRet = pstMainCtrl->m_stItemMgr.GetConfig(stDropItemData._ucItemType, stDropItemData._usItemConfigID, stItemConfigData);
        if (iRet != RET_OK)
        {
            return AnsClients(iRet);
        }

        //检查是否会满
        if (stDropItemData._ucItemType == ITEM_TYPE_CARD)
        {
            iCardEmptyGrid -= stItemConfigData._iUseGrid;
        }
        else
        {            
            iBagEmptyGrid -= stItemConfigData._iUseGrid;
        }

        if (iCardEmptyGrid < 0)
        {
            return AnsClients(ERROR_CARD_BAG_WILL_FULL);
        }
        else if (iBagEmptyGrid < 0)
        {
            return AnsClients(ERROR_BAG_WILL_FULL);
        }
        */

        stDropItem.Drop(stDropItemData);

        /*
        //取出物品
        iRet = pstMainCtrl->m_stStorageMgr.TakeOutGrid(stPlayerOnlineData._stUserGroudBag, stKey._usStorePos, stGrid);
        if (iRet != RET_OK)
        {
            return AnsClients(iRet);
        }
        */
    }

    //检查是否会满
    if (stDropItem.GetSpaceSize() > iBagEmptyGrid)
    {
        stAns.set_need_grid_count(stDropItem.GetSpaceSize() - iBagEmptyGrid);
        return AnsClients(ERROR_BAG_WILL_FULL);
    }

    if (iNeedCardGrid > iCardEmptyGrid)
    {
        return AnsClients(ERROR_CARD_BAG_WILL_FULL);
    }

    stDropItem.SetOssModule(OSS_MODULE_INSTANCE);
    iRet = pstMainCtrl->m_stItemMgr.DropItem(NULL, stReq.gid(), stDropItem);
    if (RET_OK != iRet)
    {
        return AnsClients(iRet);
    }

    //清空背包
    stPlayerOnlineData._stUserGroudBag.Clear();

    stAns.set_has_item_on_groud(stPlayerOnlineData._stUserGroudBag.BagIsEmpty() ? 0 : 1);

    CUserStorage & stUserStorage = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex]._stUserStorage;
    pstMainCtrl->m_stStorageMgr.GetData(stUserStorage, stPlayerDetailInfo._stUserStorage);
    pstMainCtrl->m_stEquipMgr.GetData(stPlayerOnlineData._stUserEquip, stPlayerDetailInfo._stUserEquip);

    //保存数据
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = stPlayerDetailInfo._uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    //pstMainCtrl->m_stNotifyMgr.Notify(stReq.gid(), NOTIFY_BAG_INFO);
    pstMainCtrl->m_stStorageMgr.SendInfoToFront(STORAGE_TYPE_GROUD, stReq.gid(), stPlayerOnlineData._stUserGroudBag, stMsgHead, stEnpHead);

    pstMainCtrl->m_stOssMgr.TriggerItem(stPlayerDetailInfo._uiGID, OSS_ITEM_PICK_UP);//oss

    return AnsClients(iRet);
}

int CCmdPickUpItem::AnsClients(int iRet)
{
    stMsgHead.set_msgret(RET_OK);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    stAns.set_ret(iRet);

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    iRet = pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true);

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_UNLOCK_GRID, CCmdUnlockGrid);
int CCmdUnlockGrid::Do(void* pData)
{
    //int iRet = 0;
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_UNLOCK_GRID ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_UNLOCK_GRID,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    _uiGID = stReq.gid();
    iRet = pstMainCtrl->CheckLogin(_uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdUnlockGrid::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    unsigned char ucStorageType = (unsigned char)(stReq.storage_type() & 0x7F);
    if ((STORAGE_TYPE_BAG != ucStorageType)  &&  (STORAGE_TYPE_WARE != ucStorageType))
    {
        return AnsClients(ERROR_UNKOWN_STORAGE_TYPE);
    }

    for (int i = 0; i < stReq.count(); i++)
    {
        unsigned short usGoldPrice;
        pstMainCtrl->m_stStorageMgr.GetUnLockGridPrice(stPlayerOnlineData._stUserStorage, ucStorageType, usGoldPrice);
        if (stPlayerBaseInfo._iGold < usGoldPrice)
        {
            return AnsClients(ERROR_GOLD_LESS);
        }

        pstMainCtrl->m_stStorageMgr.UnLockGrid (stPlayerOnlineData._stUserStorage, ucStorageType);
        iRet = pstMainCtrl->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_12, usGoldPrice);
        if (iRet)
        {
            break;
        }
    }

    CVarObjectKey stKey;
    stKey.m_u64ID = stPlayerBaseInfo._uiGID;

    stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

    pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    unsigned int uiNotifyType;
    uiNotifyType = (NOTIFY_USER_MONEY |  ((STORAGE_TYPE_BAG == ucStorageType) ? NOTIFY_BAG_INFO: NOTIFY_WARE_INFO));
    pstMainCtrl->m_stNotifyMgr.Notify(stPlayerBaseInfo._uiGID, uiNotifyType);
    return AnsClients(iRet);
}

int CCmdUnlockGrid::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_BAG_OPT, CCmdBagOpt);
int CCmdBagOpt::Do(void* pData)
{
    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_BAG_OPT ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_BAG_OPT,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    _uiGID = stReq.gid();
    iRet = pstMainCtrl->CheckLogin(_uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdBagOpt::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_INFO(this, stReq.gid());
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, stReq.gid());
    PREPARE_PLAYER_ONLINE_DATA(this, stReq.gid());

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no detail ex1 data user(%u)", _uiGID));
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1 =  pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(stReq.gid());
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    
    unsigned short usPos = stReq.pos();
    CStorageGrid stGrid;
    pstMainCtrl->m_stStorageMgr.GetGridInfoByPos(stPlayerOnlineData._stUserStorage, true, usPos, stGrid);

    bool bNeedUpdateEx1 = false;
    unsigned uiNotifyType = 0;
    switch (stReq.opt())
    {
    case 1: // 清除果实CD时间
        {
            if (ITEM_TYPE_FRUIT != stGrid._stKey._ucItemType)
            {
                CT_ERROR(("%d,%d", usPos, stGrid._stKey._ucItemType));
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            //判断宠物果实是否有效期内
            if (stGrid._iInvalidTime > pstMainCtrl->m_iNow)
            {
                return AnsClients(ERROR_FRUIT_NOT_EXPIRE);
            }

            CFruitUnitConfig stConfigData;
            iRet = pstMainCtrl->m_stItemMgr.GetFruitConfig(stGrid._stKey._uiItemID, stConfigData);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            iRet = pstMainCtrl->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_23, stConfigData._iRecoverGoldCost);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            iRet = pstMainCtrl->m_stStorageMgr.ClearTime(stPlayerOnlineData._stUserStorage, usPos, pstMainCtrl->m_iNow + MAX_FRUIT_VALIDE_TIME);
            if (iRet)
            {
                CT_ERROR(("%d, %d", iRet, _uiGID, stConfigData._iRecoverGoldCost));
                return AnsClients(iRet);
            }

            pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);
            uiNotifyType = NOTIFY_BAG_INFO | NOTIFY_USER_MONEY;
        }
        break;
    case 2: //打开卡片，放入卡片背包
        {
            if (ITEM_TYPE_CARD2 != stGrid._stKey._ucItemType)
            {
                CT_ERROR(("%d,%d", usPos, stGrid._stKey._ucItemType));
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            iRet = pstMainCtrl->m_stCardMgr.DropCard(stPlayerOnlineData._stUserCard, (unsigned short)stGrid._stKey._uiItemID, 0, false);
            if (RET_OK == iRet)
            {
                //下发数据
                MsgGridItemInfo* pstMsgGridItemInfo = stAns.mutable_item();
                pstMsgGridItemInfo->set_item_type(ITEM_TYPE_CARD);
                pstMsgGridItemInfo->set_item_config_id(stGrid._stKey._uiItemID);
                pstMsgGridItemInfo->set_item_count(1);

                //扣除背包内的物品
                pstMainCtrl->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, usPos, 1);

                //保存数据
                pstMainCtrl->m_stCardMgr.GetData(stPlayerOnlineData._stUserCard, stPlayerDetailInfo._stUserCardData);
                pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);

                //下发数据
                pstMainCtrl->m_stCardMgr.SendCardBagInfoToFront(stPlayerOnlineData._stUserCard, stMsgHead, stEnpHead);
                uiNotifyType = NOTIFY_BAG_INFO;
            }
        }
        break;
    case 3: //装备转换
        {
            bool bUseGold = false;
            if (ITEM_TYPE_EQUIP != stGrid._stKey._ucItemType)
            {
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            if (pstMainCtrl->m_stStorageMgr.GetItemCount(stPlayerOnlineData._stUserStorage, ITEM_TYPE_MATERIAL, 192) < 1)
            {
                if (stPlayerBaseInfo._iGold < EQUIP_TRANS_FORM_GOLD)
                {
                    return AnsClients(ERROR_GOLD_LESS);
                }

                bUseGold = true;
            }

            pstMainCtrl->m_stOssMgr.ClearKeyValueList();//oss
                    
            unsigned short usNewEquipConfigId = (unsigned short)stReq.para_1();            
            iRet = pstMainCtrl->m_stEquipMgr.CheckTransform (stPlayerOnlineData._stUserEquip, stGrid._stKey._uiItemID, usNewEquipConfigId);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            if (bUseGold)
            {
                pstMainCtrl->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_38, EQUIP_TRANS_FORM_GOLD);
            }
            else
            {
                iRet = pstMainCtrl->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, ITEM_TYPE_MATERIAL, 192, 1);
                if (iRet)
                {
                    return AnsClients(ERROR_LACK_ZHF);
                }
            }

            unsigned int uiNewEquipId = 0;
            iRet = pstMainCtrl->m_stEquipMgr.Transform(stPlayerOnlineData._stUserEquip, stGrid._stKey._uiItemID, usNewEquipConfigId, uiNewEquipId);
            if (RET_OK == iRet)
            {
                stGrid._stKey._uiItemID = uiNewEquipId;
                iRet = pstMainCtrl->m_stStorageMgr.ReplaceGrid(stPlayerOnlineData._stUserStorage, true, usPos, stGrid);
                if (iRet)
                {
                    CT_ERROR(("%d, %d, %d", iRet, _uiGID, uiNewEquipId));
                    return AnsClients(iRet);
                }

                //保存数据
                pstMainCtrl->m_stEquipMgr.GetData(stPlayerOnlineData._stUserEquip, stPlayerDetailInfo._stUserEquip);                

                uiNotifyType = NOTIFY_BAG_INFO;
                if (bUseGold)
                {
                    uiNotifyType |= NOTIFY_USER_MONEY;
                }
            }
            else
            {
                CT_ERROR(("%d, %d, %d", iRet, _uiGID));
            }

            pstMainCtrl->m_stOssMgr.TriggerItem(stPlayerBaseInfo._uiGID, OSS_ITEM_TRANSFORM_EQUIP);//oss
        }
        break;
    
    case 4: //开启宝箱争夺
        {
            if (0 != stPlayerDetailEx1._stFightForBox._ucHasBegin)
            {
                return AnsClients(ERROR_FIGHT_FOR_BOX_ERROR1);
            }

            if (ITEM_TYPE_USABLE != stGrid._stKey._ucItemType
                && 1 != stGrid._stKey._uiItemID)
            {
                CT_ERROR(("%d,%d,%d", usPos, stGrid._stKey._ucItemType, stGrid._stKey._uiItemID));
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            //扣除背包内的物品
            iRet = pstMainCtrl->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, usPos, 1);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            iRet = pstMainCtrl->m_stActMgr.StartFightForBox(stPlayerDetailEx1._stFightForBox);
            if (iRet)
            {
                CT_ERROR(("%d,%d", _uiGID, iRet));
                return AnsClients(iRet);
            } 

            pstMainCtrl->m_stActMgr.SendFightForBoxInfoToFront (_uiGID, stPlayerDetailEx1._stFightForBox);

            bNeedUpdateEx1 = true;
            uiNotifyType = NOTIFY_BAG_INFO;
        }
        break;
        
    case 5: //招募伙伴
        {
            PREPARE_UNACT_PARTNER_INFO(this, stPlayerBaseInfo._uiGID);
            ASSERT_UNACT_PARTNER_PREPARED(stPlayerBaseInfo._uiGID);

            PREPARE_PLAYER_DETAIL_EX1_INFO(this, stPlayerBaseInfo._uiGID);
            ASSERT_PLAYER_DETAIL_EX1_INFO(stPlayerBaseInfo._uiGID);

            iIndex = pstMainCtrl->m_stUnactPartnerInfoHash.HashFind(
                stPlayerBaseInfo._uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no unact partner data user(%u)",
                    stPlayerBaseInfo._uiGID));
                return AnsClients(RET_SYS_ERROR);
            }
            CUnactPartnerInfo& stUnactPartnerInfo =
                pstMainCtrl->m_stUnactPartnerInfoHash[iIndex];

            iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(
                stPlayerBaseInfo._uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("get user detail ex1 info error, uid = %u",
                    stPlayerBaseInfo._uiGID));
                return AnsClients(RET_SYS_ERROR);
            }
            CPlayerDetailInfoEx1& stPlayerDetailEx1Info =
                pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

            if (ITEM_TYPE_PARTNER != stGrid._stKey._ucItemType)
            {
                CT_ERROR(("%d,%d", usPos, stGrid._stKey._ucItemType));
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            if (stGrid._shCount < 1)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            //stGrid._stKey._uiItemID伙伴ID
            short shPartnerID = (short)stGrid._stKey._uiItemID;
            if (shPartnerID <= 0)
            {
                return AnsClients(ERROR_PARTNER_ERROR_CFG);
            }

            iRet = pstMainCtrl->m_stPartnerMgr.CheckPartnerJoin(shPartnerID,
                CPartnerMgr::PARTNER_JOIN_TYPE_SYSTEM, stPlayerBaseInfo,
                stPlayerDetailInfo, stUnactPartnerInfo, stPlayerOnlineData);
            if (iRet != RET_OK)
            {
                return AnsClients(iRet);
            }

            iRet = pstMainCtrl->m_stPartnerMgr.PartnerJoinUseItem(shPartnerID,
                stPlayerBaseInfo, stPlayerDetailInfo, stUnactPartnerInfo,
                stPlayerOnlineData, stPlayerDetailEx1Info);

            if (iRet != RET_OK)
            {
                CT_ERROR(("role(%u) join item partner(%d) error(%d)",
                    stPlayerBaseInfo._uiGID, shPartnerID, iRet));
                return AnsClients(iRet);
            }
            
            //扣除物品
            if (iRet == RET_OK)
            {
                //扣除背包内的物品
                iRet = pstMainCtrl->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, usPos, 1);
                if (iRet)
                {
                    return AnsClients(iRet);
                }

                uiNotifyType = NOTIFY_BAG_INFO;
            }
        }
        break;

    case 6:  //获得坐骑
        {
            if (ITEM_TYPE_MOUNT != stGrid._stKey._ucItemType)
            {
                CT_ERROR(("%d,%d,%d", usPos, stGrid._stKey._ucItemType, stGrid._stKey._uiItemID));
                return AnsClients(ERROR_WRONG_ITEM_TYPE);
            }

            CMountData & stMount = stPlayerDetailEx1._stMount;
            unsigned int uiMountId = stGrid._stKey._uiItemID;

            if (!CMainCtrl::m_pstMain->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_25,
                stPlayerBaseInfo, stPlayerOnlineData))
            {
                return AnsClients(ERROR_SYS_NOT_OPEN);
            }

            unsigned short usNeedRoleLevl = pstMainCtrl->m_stMountMgr.GetMountNeedRoleLevel(uiMountId);
            if(stPlayerBaseInfo._shLevel < usNeedRoleLevl)
            {
                return AnsClients(ERROR_MOUNT_OPT_LEVEL);
            }

            iRet = pstMainCtrl->m_stMountMgr.CheckAddMount(stMount, uiMountId);
            if (iRet)
            {
                return AnsClients(iRet);
            }           

            //扣除背包内的物品
            iRet = pstMainCtrl->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, usPos, 1);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            iRet = stMount.AddMount (uiMountId);
            if (iRet)
            {
                CT_ERROR(("%d, %d, %d", iRet, _uiGID, uiMountId));
            }

            bNeedUpdateEx1 = true;
            uiNotifyType = NOTIFY_BAG_INFO;
        }
        break;

    case  7: // 获得时装
        {
            iRet = pstMainCtrl->m_stFashionMgr.OpenFashionInBag(
                stPlayerBaseInfo, stPlayerDetailEx1._stUserFasion,
                stPlayerOnlineData, stGrid);
            if (RET_OK == iRet)
            {
                bNeedUpdateEx1 = true;
                uiNotifyType = NOTIFY_BAG_INFO;
            }
        }
        break;

    default:
        return AnsClients(ERROR_UNSURPORT_BAG_OPT);
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    CVarObjectKey stKey;
    stKey.m_u64ID = stPlayerBaseInfo._uiGID;

    stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

    pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    if (bNeedUpdateEx1)
    {
        CVarObjectKey stKey;
        stKey.m_u64ID = stPlayerDetailEx1._uiGID;
        stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailEx1, VOP_UPDATE);
    }

    pstMainCtrl->m_stNotifyMgr.Notify(_uiGID, uiNotifyType);
    return AnsClients(iRet);
}

int CCmdBagOpt::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

//////////////////////活动扩展存储/////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_ACT_STORAGE, CCmdActStorage);
int CCmdActStorage::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_ACT_STORAGE ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_ACT_STORAGE,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    iSubCmd = stReq.req_type();
    uiGID = stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    stAns.set_gid((int)uiGID);
    stAns.set_req_type(iSubCmd);

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdActStorage::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    int iIndex = 0;

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_EX1_INFO(uiGID);

    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);
    ASSERT_PLAYER_ONLINE_DATA_PREPARED(uiGID);

    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no base data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBase = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBase._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no detail ex1 data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1 =
        pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnline =
        pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    iRet = pstMainCtrl->m_stStorageMgr.GetActStorageItem(stPlayerDetailEx1,
        stPlayerOnline, stReq, stAns);

    if (iRet)
    {
        CT_TRACE(("user(gid=%u) deal act storage op(sub=%d) error(%d)",
            uiGID, iSubCmd, iRet));
        return AnsClients(iRet);
    }

    return AnsClients(RET_OK);
}

int CCmdActStorage::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,
            true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

